//
//  YYGraphics.swift
//  CodeLibrary_Swift
//
//  Created by 陆文宇 on 2017/2/3.
//  Copyright © 2017年 陆文宇. All rights reserved.
//

import UIKit

extension UIImage {
    
    /// 裁剪方式
    enum YYGraphicCutOption {
        case rect           // 正方形
        case circle         // 圆形或椭圆
        case roundedRect    // 圆角
    }
    
    /**
     *  计算裁剪Frame，获取裁剪后的图片
     *
     *  - Parameters:
     *      - param rect:      相对于`imageView`的父视图的Frame
     *      - param imageView: 需要裁剪的图片视图
     *      - param scale:     { width: 初始的`imageView.image.size.width`:`imageView.frame.size.width`,
                                 height: 初始的`imageView.image.size.height`:`imageView.frame.size.height` }
     *
     *  - Returns 裁剪后的图片
     */
    static func yy_crop(to rect: CGRect, in imageView: UIImageView, scale: CGSize) -> UIImage! {
        let viewScale = sqrt(pow(imageView.transform.a, 2) + pow(imageView.transform.b, 2))
        var viewRotation = CGFloat(acosf(Float(imageView.transform.a / viewScale)))
        if imageView.transform.b < 0 {
            viewRotation = -viewRotation
        }
        
        var imageFrame = CGRect.zero
        imageFrame.origin.x = (rect.origin.x - imageView.frame.origin.x) / viewScale * scale.width
        imageFrame.origin.x = (rect.origin.y - imageView.frame.origin.y) / viewScale * scale.height
        imageFrame.size.width = rect.size.width / viewScale * scale.width
        imageFrame.size.height = rect.size.height / viewScale * scale.height
        
        return imageView.image?.yy_compress(for: .rect, imageFrame: imageFrame, rotation: viewRotation, cornerRadius: 0)
    }
    
    /**
     *  获取裁剪后的图片
     *
     *  - Parameters:
     *      - option:       裁剪方式， 默认为正方形
     *      - imageFrame:   图片Frame，设置zero为全图，默认zero
     *      - rotation:     图片旋转角度，默认0
     *      - cornerRadius: 如果设置切圆角才需要设置，默认5
     *
     *  - Returns 裁剪后的图片
     */
    func yy_compress(for cutOption: YYGraphicCutOption = .rect, imageFrame: CGRect = .zero, rotation: CGFloat = 0, cornerRadius: CGFloat = 5) -> UIImage! {
        var imageSelf = self;
        var ciImageSelf = CIImage(image: imageSelf)
        //        ciImageSelf = ciImageSelf!.settingProperties([kCIImageAutoAdjustCrop: true, kCIImageAutoAdjustLevel: true])
        
        guard ciImageSelf != nil else {
            return nil
        }
        
        if rotation != 0 {
            ciImageSelf = ciImageSelf?.transformed(by: CGAffineTransform(rotationAngle: -rotation))
            ciImageSelf = ciImageSelf?.transformed(by: CGAffineTransform(translationX: -ciImageSelf!.extent.origin.x, y: -ciImageSelf!.extent.origin.y))
        }
        
        if imageFrame.size.width != 0 {
            let imageTransform = CGAffineTransform(translationX: -imageFrame.origin.x, y: -(ciImageSelf!.extent.size.height - imageFrame.size.height - imageFrame.origin.y))
            ciImageSelf = ciImageSelf?.transformed(by: imageTransform)
            ciImageSelf = ciImageSelf!.cropped(to: CGRect(x: 0, y: 0, width: imageFrame.size.width, height: imageFrame.size.height))
            imageSelf = UIImage(ciImage: ciImageSelf!)
        }
        
        let width = imageSelf.size.width == 0 ? imageFrame.size.width : imageSelf.size.width
        let height = imageSelf.size.height == 0 ? imageFrame.size.height : imageSelf.size.height
        let targetRect = CGRect(x: 0, y: 0, width: width, height: height)
        
        UIGraphicsBeginImageContextWithOptions(targetRect.size, false, 0);
        let context: CGContext? = UIGraphicsGetCurrentContext();
        
        if context == nil {
            return nil
        }
        
        switch cutOption {
        case .rect:
            context?.addRect(targetRect)
            context?.closePath()
        case .circle:
//            context?.addArc(center: CGPoint(x: targetWidth / 2, y: targetHeight / 2), radius: targetWidth / 2, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: false)
            context?.addEllipse(in: targetRect)
            context?.closePath()
        case .roundedRect:
            context?.move(to: CGPoint(x: 0, y: cornerRadius))
            context?.addArc(tangent1End: CGPoint(x: 0, y: 0), tangent2End: CGPoint(x: cornerRadius, y: 0), radius: cornerRadius)
            context?.addLine(to: CGPoint(x: width - cornerRadius, y: 0))
            context?.addArc(tangent1End: CGPoint(x: width, y: 0), tangent2End: CGPoint(x: width, y: width), radius: cornerRadius)
            context?.addLine(to: CGPoint(x: width, y: height - cornerRadius))
            context?.addArc(tangent1End: CGPoint(x: width, y: height), tangent2End: CGPoint(x: cornerRadius, y: height), radius: cornerRadius)
            context?.addLine(to: CGPoint(x: cornerRadius, y: height))
            context?.addArc(tangent1End: CGPoint(x: 0, y: height), tangent2End: CGPoint(x: 0, y: cornerRadius), radius: cornerRadius)
            context?.addLine(to: CGPoint(x: 0, y: cornerRadius))
            context?.closePath()
        }
        
        let aColor: UIColor = UIColor(patternImage: self)
        context?.setFillColor(aColor.cgColor)
        context?.drawPath(using: .fill)
        let compressedImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return compressedImage
    }
    
    func yy_JPEGData() -> Data! {
        UIGraphicsBeginImageContext(size)
        draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return UIImageJPEGRepresentation(newImage!, JPEG_CompressionQuality)
    }
    
    static func yy_createName() -> String {
        return "\(Date().yy_formateString(formate: "yyyyMMddhhmmss"))_\(arc4random() % 10000).jpg"
    }
    
}
